package nl.weeaboo.sh.objects;

import java.awt.Rectangle;

import javax.media.opengl.GL;

import nl.weeaboo.game.gl.BlendMode;
import nl.weeaboo.game.gl.GLImage;
import nl.weeaboo.game.gl.GLManager;
import nl.weeaboo.game.input.UserInput;
import nl.weeaboo.sh.Game;
import nl.weeaboo.sh.danmaku.SpellUtil;
import nl.weeaboo.sh.danmaku.UniverseAdapter;
import nl.weeaboo.sh.level.Level;
import nl.weeaboo.sh.view.Camera;
import nl.weeaboo.sh.view.CharaImage;
import nl.weeaboo.sh.view.anim.Animation;
import nl.weeaboo.sh.view.anim.AnimationFrame;

public class Boss extends Monster {

	private int timeLeft;
	private int timeFrac;
	private GLImage bossIndicatorI;
	
	protected Animation anim;
	protected int spellcard;
	protected boolean keepWithinRoom;
	
	public Boss(Game game, Level level, CharaImage image) {
		super(game, level, image);
	
		bossIndicatorI = game.getImage("menu/osd.png#bossIndicator", false);
		
		setMaxHp(10);
		
		keepWithinRoom = true;
		floating = true;
		dir = -1;
		
		anim = Animation.create(game, image.getGLImage().getTexture().getId(), true,
				image.getGLImage().getTexRect().getId(), 60);
	}

	//Functions	
	public void destroy() {
		if (nextSpellcard(spellcard + 1)) {
			return; //Restart
		}
		
		super.destroy();
		
		level.addEffect(new Explosion(game, level, image, x, y, rotation, dir==-1, false));
		level.onBossDefeated(this);
	}

	public void update(UserInput input, float dt) {		
		anim = anim.update(1);
		AnimationFrame currentFrame = anim.getCurrentFrame();
		if (currentFrame != null) {
			setImage((CharaImage)currentFrame.getImage());
		}		

		timeFrac++;
		if (timeFrac >= 60) {
			timeFrac = 0;
			if (timeLeft > 0) timeLeft--;
		}
		
		dir = (speedX <= -1 ? -1 : (speedX >= 1 ? 1 : dir));
		
		if (keepWithinRoom) {
			UniverseAdapter ua = level.getUniverseAdapter();
			if (ua != null) {
				Rectangle r = ua.getBounds();
				
				x = Math.max(r.x, Math.min(r.x+r.width, x));
				y = Math.max(r.y, Math.min(r.y+r.height, y));
			}			
		}
		
		super.update(input, dt);		
	}
	
	protected void drawImage(GLManager glm) {
		super.drawImage(glm);

		if (isInvincible()) {
			glm.setBlendMode(BlendMode.LIGHT);
			glm.pushColor();
			
			float s = SpellUtil.fastSin(invincibilityTime);
			glm.mixColor(s, s, s, 1);
	
			super.drawImage(glm);
			glm.popColor();
			glm.setBlendMode(BlendMode.DEFAULT);
		}
	}
	
	public void drawForeground(GLManager glm) {		
		GL gl = glm.getGL();
		
		Rectangle ib = getImageBounds(dir == -1);
		Rectangle lb = level.getVisibleRect();		
		if (!ib.intersects(lb)) {
			Camera camera = level.getCamera();
			int iw = bossIndicatorI.getWidth();
			int ih = bossIndicatorI.getHeight();
			int iw2 = iw>>1;
			int ih2 = ih>>1;
			
			float a = SpellUtil.angleTo(camera.getX(), camera.getY(), x, y);
			float sx = 480 * SpellUtil.fastSin(a) / camera.getScale();
			float sy = 480 * -SpellUtil.fastCos(a) / camera.getScale();
			
			int w2 = Math.round(400 / camera.getScale());
			int h2 = Math.round(216 / camera.getScale());
			sx = camera.getX() + Math.max(-w2+iw2, Math.min(w2-iw2, sx));
			sy = camera.getY() + Math.max(-h2+ih2, Math.min(h2-ih2, sy));
			
			gl.glPushMatrix();
			gl.glTranslatef(sx, sy, 0);
			gl.glRotatef(SpellUtil.angleToDegrees(a), 0, 0, -1);
			bossIndicatorI.draw(glm, -iw2, -ih2, iw, ih);
			gl.glPopMatrix();
		}
	}
	
	public void startSpell(int hp, int time) {
		setMaxHp(hp);
		setHp(hp);
		setTimeLeft(time);
		
		setInvincibilityTime(90);
	}
	
	protected boolean nextSpellcard(int newSpellcardNum) {
		return false;
	}

	//Getters
	public int getTimeLeft() { return timeLeft; }
	
	//Setters
	public void setTimeLeft(int t) {
		timeFrac = 0;
		timeLeft = t;
	}
	
}
